package cn.mw.cmdb.processor;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.mw.cmdb.entity.InstanceGroupByPathAndStatus;
import cn.mw.cmdb.entity.ModelGroupInfo;
import cn.mw.cmdb.entity.ModelInfo;
import cn.mw.cmdb.param.GroupSearchParam;
import cn.mw.cmdb.param.InstanceSearchParam;
import cn.mw.cmdb.param.ModelSearchParam;
import cn.mw.cmdb.param.TableSearchParam;
import cn.mw.cmdb.service.impl.CmdbServiceManage;
import cn.mw.cmdb.service.impl.CustomModelServiceImpl;
import cn.mw.cmdb.service.impl.InstanceServiceImpl;
import cn.mw.cmdb.service.impl.ModelGroupServiceImpl;
import cn.mw.cmdb.util.AssetsTool;
import cn.mw.cmdb.util.CMDBTool;
import cn.mw.components.mongodb.entity.CriteriaOpsType;
import cn.mw.components.mongodb.entity.SubCondition;
import cn.mw.microMonitorCommon.api.cmdb.TreeView;
import cn.mw.microMonitorCommon.util.SpringUtils;
import org.springframework.util.StringUtils;

import java.util.*;

import static cn.mw.cmdb.util.ValConvertUtil.strValueConvert;

public class TreeProcessorParentModel implements TreeProccessorTable {

    private CmdbServiceManage cmdbServiceManage;

    private TableSearchParam tableSearchParam;

    public TreeProcessorParentModel(CmdbServiceManage cmdbServiceManage, TableSearchParam tableSearchParam) {
        this.cmdbServiceManage = cmdbServiceManage;
        this.tableSearchParam = tableSearchParam;
    }

    @Override
    public List genTreeData(TableDataProcessorContext context) throws Exception {
        List<TreeView> list = new ArrayList();
        InstanceServiceImpl instanceService = (InstanceServiceImpl) cmdbServiceManage.getModelService(InstanceServiceImpl.ID);
        InstanceSearchParam param = new InstanceSearchParam();
        BeanUtil.copyProperties(context.getTableSearchParam(), param, CopyOptions.create().setIgnoreNullValue(true));

        List<InstanceGroupByPathAndStatus> groupRet = instanceService.groupCountByPathAndStatus(param);
        Set<String> modelIds = new HashSet<>();
        Set<String> groupSet = new HashSet<>();
        Map<String, List<AssetsTool.ItemAssetsStatusContext>> idContextMap = AssetsTool.initModelAndGroupIdSet(modelIds, groupSet, groupRet);

        ModelGroupServiceImpl modelGroupService = (ModelGroupServiceImpl) cmdbServiceManage.getModelService(ModelGroupServiceImpl.ID);
        List<ModelGroupInfo> groupTree = null;
        GroupSearchParam searchParam = new GroupSearchParam();
        String parentGroupId = SpringUtils.getPropertiesValue("base.parentGroupId");
        tableSearchParam.setId(parentGroupId);
        Map<String, SubCondition> condition = new HashMap<>();
        BeanUtil.copyProperties(context.getTableSearchParam(), searchParam, CopyOptions.create().setIgnoreNullValue(true));
        if (StringUtils.hasText(tableSearchParam.getId())) {
            condition.put(CMDBTool.getFieldName(ModelGroupInfo::getId), new SubCondition(CriteriaOpsType.in.name(), tableSearchParam.getId()));
        }
        searchParam.setCondition(condition);
        groupTree = modelGroupService.getParentModelGroupList(searchParam);
        if (null != groupTree) {
            list.addAll(groupTree);
        }
        CustomModelServiceImpl customModelService = (CustomModelServiceImpl) cmdbServiceManage.getModelService(CustomModelServiceImpl.ID);
        ModelSearchParam modelSearchParam = new ModelSearchParam();
        if (tableSearchParam != null && StringUtils.hasText(tableSearchParam.getId())) {
            condition = new HashMap<>();
            condition.put(CMDBTool.getFieldName(ModelInfo::getGroupPath), new SubCondition(CriteriaOpsType.in.name(), tableSearchParam.getId()));
            modelSearchParam.setCondition(condition);
        }
        List<ModelInfo> modelInfos = customModelService.getAllModelByParentGroup(modelSearchParam);
        if (null != modelInfos) {
            list.addAll(modelInfos);
        }
        for (TreeView treeView : list) {
            String id = strValueConvert(treeView.getId());
            List<AssetsTool.ItemAssetsStatusContext> contexts = idContextMap.get(id);
            if (null != contexts) {
                treeView.setCount(AssetsTool.calcItemAssetsStatusCount(contexts));
                treeView.setItemAssetsStatus(AssetsTool.calcItemAssetsStatusContext(contexts, treeView));
            }
        }
        return list;
    }
}
